package xjtu.sad.zbsj.template.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xjtu.sad.zbsj.common.PageParam;
import xjtu.sad.zbsj.dao.template.TemplateDao;
import xjtu.sad.zbsj.template.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class TemplateServiceImpl implements TemplateService {

    @Resource
    private TemplateDao templateDao;

    /**
     * 获得某用户所有的模板列表
     *
     * @param userId    用户id
     * @param pageParam 分页信息
     * @return 该用户所有的模板列表
     */
    @Override
    public Page<Template> getTemplateList(Integer userId, PageParam pageParam) {
        PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        List<Template> templateList = templateDao.getTemplateList(userId);
        Page<Template> templatePageList = (Page<Template>) templateList;

        // 遍历模板列表寻找其属性值列表与属性名列表
        for (Template template : templateList) {
            getTemplateAttr(template);// 获取所有模板的属性信息
        }

        return templatePageList;
    }

    /**
     * 获得所有默认模板列表
     *
     * @return 默认模板列表
     */
    @Override
    public Page<Template> getDefaultTemplateList(PageParam pageParam) {
        PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        List<Template> templateList = templateDao.getTemplateList(null);
        Page<Template> templatePageList = (Page<Template>) templateList;

        // 遍历模板列表寻找其属性值列表与属性名列表
        for (Template template : templateList) {
            getTemplateAttr(template);// 获取所有模板的属性信息
        }

        return templatePageList;
    }

    /**
     * 获得某个模板的详细信息
     *
     * @param templateId 模板id
     * @return 模板的具体信息
     */
    @Override
    public Template getTemplateInfo(Integer templateId) {
        Template template = templateDao.getTemplateInfo(templateId);
        getTemplateAttr(template);
        return template;
    }

    /**
     * 添加新模板
     *
     * @param template 新模板信息
     * @return 是否添加成功
     */
    @Override
    public boolean addNewTemplate(Template template) {
        try {
            // 插入模板信息
            templateDao.addNewTemplate(template);

            // 插入属性名
            for (Attribute attr : template.getAttrs()) {
                attr.setTemplateId(template.getTemplateId());
            }
            templateDao.addNewAttribute(template.getAttrs());// 在mybatis中自动将生成的主键赋值到attrId中
            System.out.println(template.getAttrs());

            // 在属性值和属性限制中加入属性id
            List<AttributeValue> attributeValueList = new ArrayList<>();
            List<AttributeProperty> attributePropertyList = new ArrayList<>();
            getValueAndPropertyList(template.getAttrs(), attributeValueList, attributePropertyList);

            // 插入属性值
            if (attributeValueList.size() != 0) {
                templateDao.addNewAttributeValue(attributeValueList);
            }

            // 插入属性限制
            if (attributePropertyList.size() != 0) {
                templateDao.addNewAttributeProperty(attributePropertyList);
            }
            return true;

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 修改模板信息
     *
     * @param template 模板信息
     * @return 修改结果
     */
    @Override
    public boolean changeTemplateInfo(Template template) {
        try {
            // 修改模板基础信息
            templateDao.changeTemplateInfo(template);

            // 对属性名进行分类处理
            List<Attribute> changedAttributeList = new ArrayList<>();
            List<Attribute> newAttributeList = new ArrayList<>();
            List<Attribute> deletedAttributeList = new ArrayList<>();

            for (Attribute attribute : template.getAttrs()) {
                switch (attribute.getUpdate()) {
                    case 1:
                        changedAttributeList.add(attribute);
                        break;
                    case 2:
                        newAttributeList.add(attribute);
                        attribute.setTemplateId(template.getTemplateId());
                        break;
                    case 3:
                        deletedAttributeList.add(attribute);
                        break;
                }
            }

            // 获得属性值信息
            // 修改的属性
            if (changedAttributeList.size() != 0) {
                List<AttributeValue> changedAttributeValueList = new ArrayList<>();
                List<AttributeProperty> changedAttributePropertyList = new ArrayList<>();
                getValueAndPropertyList(changedAttributeList, changedAttributeValueList, changedAttributePropertyList);

                // 修改属性名信息
                templateDao.changeAttributeInfo(template.getAttrs());

                // 修改属性值信息
                if (changedAttributeValueList.size() != 0) {
                    templateDao.changeAttributeValueInfo(changedAttributeValueList);
                }

                // 修改属性约束信息
                templateDao.changeAttributePropertyInfo(changedAttributePropertyList);
            }

            // 新加的属性
            if (newAttributeList.size() != 0) {
                List<AttributeValue> newAttributeValueList = new ArrayList<>();
                List<AttributeProperty> newAttributePropertyList = new ArrayList<>();

                // 添加属性名信息,以获取propertyId
                templateDao.addNewAttribute(newAttributeList);

                getValueAndPropertyList(newAttributeList, newAttributeValueList, newAttributePropertyList);


                // 添加属性值信息
                if (newAttributeValueList.size() != 0) {
                    templateDao.addNewAttributeValue(newAttributeValueList);
                }

                // 添加属性约束信息
                templateDao.addNewAttributeProperty(newAttributePropertyList);
            }

            // 删除的属性
            if (deletedAttributeList.size() != 0) {
                List<AttributeValue> deletedAttributeValueList = new ArrayList<>();
                List<AttributeProperty> deletedAttributePropertyList = new ArrayList<>();
                getValueAndPropertyList(deletedAttributeList, deletedAttributeValueList, deletedAttributePropertyList);

                // 删除属性值信息
                if (deletedAttributeValueList.size() != 0) {
                    templateDao.delAttributeValue(deletedAttributeValueList);
                }

                // 删除属性约束信息
                templateDao.delAttributeProperty(deletedAttributePropertyList);

                // 删除属性名信息
                templateDao.delAttribute(deletedAttributeList);
            }

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 从属性列表中得到所有属性名列表和属性约束列表
     *
     * @param attributeList         属性名列表
     * @param attributeValueList    属性值列表
     * @param attributePropertyList 属性约束列表
     */
    private void getValueAndPropertyList(List<Attribute> attributeList, List<AttributeValue> attributeValueList, List<AttributeProperty> attributePropertyList) {
        for (Attribute attribute : attributeList) {
            // 设置属性值中的属性名id
            for (AttributeValue attributeValue : attribute.getAttrValues()) {
                attributeValue.setAttrId(attribute.getAttrId());
                attributeValueList.add(attributeValue);
            }
            // 属性限制中的属性名id,即属性限制中的主键
            AttributeProperty attributeProperty = attribute.getAttributeProperty();
            System.out.println(attributeProperty);
            attributeProperty.setAttrPropertyId(attribute.getAttrId());
            attributePropertyList.add(attributeProperty);
        }
    }

    /**
     * 删除模板
     *
     * @param template 模板信息
     * @return 删除结果
     * 1:该模板正在被使用
     * 2:业务处理错误
     * 3:处理成功
     */
    @Override
    public Integer deleteTemplate(Template template) {
        try {
            // 先检查这个模板是不是公共模板,如果是的话需要检查有没有人正在使用,如果正在使用则不能删除
            if (template.getPublicAccess()) {
                // 说明是公共模板,需要检查是否有其他任务正在使用
                Integer taskCount = templateDao.getTemplateUseCount(template.getTemplateId());
                if (taskCount > 0) {
                    return 1;
                }
            }

            // 获得属性名和属性约束列表
            List<AttributeValue> attributeValueList = new ArrayList<>();
            List<AttributeProperty> attributePropertyList = new ArrayList<>();
            getValueAndPropertyList(template.getAttrs(), attributeValueList, attributePropertyList);

            // 删除属性约束
            templateDao.delAttributeProperty(attributePropertyList);

            // 删除属性名
            if (attributeValueList.size() != 0) {
                templateDao.delAttributeValue(attributeValueList);
            }

            // 删除属性值
            templateDao.delAttribute(template.getAttrs());

            // 删除模板
            templateDao.delTemplate(template.getTemplateId());

            return 3;
        } catch (Exception e) {
            e.printStackTrace();
            return 2;
        }
    }

    /**
     * 获得除模板创建者之外使用该模板的其他用户数量
     *
     * @param templateId 模板id
     * @return 除创建者之外使用的用户数量
     */
    @Override
    public Integer getTemplateOtherUseCount(Integer templateId) {
        Integer userId = templateDao.getCreateUserId(templateId);// 获取创建模板的用户id
        return templateDao.getOtherUseCount(templateId, userId);
    }

    /**
     * 修改某个模板的发布状态
     *
     * @param templateId   模板id
     * @param publicAccess 访问状态
     * @return 修改结果
     */
    @Override
    public boolean changePublishStatus(Integer templateId, Boolean publicAccess) {
        try {
            templateDao.changePublishStatus(templateId, publicAccess);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获得分页总数
     *
     * @param pageKind 分页类型:个人模板列表,默认模板列表,领取信息列表
     * @param userId   用户id
     * @return 分页总数
     */
    @Override
    public Integer getTotalPageNum(String pageKind, Integer userId) {
        Integer totalNum = templateDao.getTotalNum(pageKind, userId);
        return totalNum;
    }

    /**
     * 获取模板的属性信息
     *
     * @param template 模板
     */
    public void getTemplateAttr(Template template) {
        List<Attribute> attributeList = templateDao.getAttributeList(template.getTemplateId());// 获得所有的属性列表
        template.setAttrs(attributeList);
        for (Attribute attr : attributeList) {

            // 获得所有的属性值列表
            List<AttributeValue> attributeValueList = templateDao.getAttributeValueList(attr.getAttrId());
            attr.setAttrValues(attributeValueList);

            // 获得属性约束
            AttributeProperty attributeProperty = templateDao.getAttributeProperty(attr.getAttrId());
            attr.setAttributeProperty(attributeProperty);
        }
    }
}
